package physicsModeler;

import java.awt.*;
import java.util.ArrayList;

import physicsModeler.objects.DrawObject;
import physicsModeler.Vector;

public class PhysXProcessor 
{
	boolean hasGravity = true;
	private final Vector gravity = new Vector(0, .098);
	private Toolkit toolkit = Toolkit.getDefaultToolkit();
	private Dimension dim   = toolkit.getScreenSize();
	public PhysXProcessor()
	{
		
	}
	
	public void handleEvents(ArrayList<DrawObject> objects)
	{	

		for (int i = 0; i < objects.size(); i++)
		{
			handleYAxis(objects.get(i));
			handleXAxis(objects.get(i));
		}
		collisions(objects);
		
	}
	
	private void collisions(ArrayList<DrawObject> objects) {
		// TODO Auto-generated method stub
		for (int i = 0; i < objects.size(); i++)
		{
			for (int x = i; x < objects.size(); x++)
			{
				
				if ((objects.get(i).getPositionX() + objects.get(i).getDiameter() > objects.get(x).getPositionX() &&
					 objects.get(i).getPositionX() + objects.get(i).getDiameter() < objects.get(x).getPositionX() + objects.get(x).getDiameter() &&
					 objects.get(i).getPositionY() + objects.get(i).getDiameter() > objects.get(x).getPositionY() &&
					 objects.get(i).getPositionY() + objects.get(i).getDiameter() < objects.get(x).getPositionY() + objects.get(x).getDiameter()) 
					 ||
					 (objects.get(x).getPositionX() + objects.get(x).getDiameter() > objects.get(i).getPositionX() &&
					  objects.get(x).getPositionX() + objects.get(x).getDiameter() < objects.get(i).getPositionX() + objects.get(i).getDiameter() &&
					  objects.get(x).getPositionY() + objects.get(x).getDiameter() > objects.get(i).getPositionY() &&
					  objects.get(x).getPositionY() + objects.get(x).getDiameter() < objects.get(i).getPositionY() + objects.get(i).getDiameter()))
				{
					objects.get(i).getVelocity().reverseX();
				//	objects.get(i).getVelocity().multScalarToX(objects.get(i).getCoefRestitution());
					objects.get(x).getVelocity().reverseX();
					//objects.get(x).getVelocity().multScalarToX(objects.get(x).getCoefRestitution());
					applyVelocity(objects.get(i));
					applyVelocity(objects.get(x));
				}
			}
		}
		
	}

	private void handleXAxis(DrawObject object) 
	{
		checkWidthCollision(object);
	}

	private void handleYAxis(DrawObject object)
	{
		if (object.isHasGravity())
			object.setAcceleration(gravity);
		else
		{
			object.setAcceleration(new Vector(object.getAcceleration().getX(), 0));
			object.setVelocity(new Vector(object.getVelocity().getX(), 0));
		}
		
		checkHeightCollision(object);
		applyAcceleration(object);
		applyVelocity(object);
	}
	
	private void checkHeightCollision(DrawObject object) 
	{
		if (object.positionY() > dim.getHeight() - object.getDiameter() && object.isHasGravity())
			object.setPosition(new Vector(object.getPositionX(), dim.getHeight() - object.getDiameter()));
		
		if (object.positionY() == dim.getHeight() - object.getDiameter() || object.positionY() == 0)
		{
			object.getVelocity().reverseY();
			object.getVelocity().multScalarToY(object.getCoefRestitution());
			checkForStationary(object);
		}
	}
	

	private void checkWidthCollision(DrawObject object) 
	{
		if (object.getPositionX() < 0 || object.getPositionX() > dim.getWidth() - object.getDiameter())
		{
			object.getVelocity().reverseX();
			object.getAcceleration().reverseX();
		}
	}	

	private void checkForStationary(DrawObject object) 
	{
		if (Math.abs(object.getVelocity().getY()) < .5)
		{
			object.setHasGravity(false);
		}
	}

	private void applyAcceleration(DrawObject object)
	{
		object.getVelocity().vectorAddition(object.getAcceleration());			                   
	}
	
	private void applyVelocity(DrawObject object)
	{
		object.getPosition().vectorAddition(object.getVelocity());
	}

}